package com.lcg.word

import android.media.MediaPlayer
import androidx.compose.runtime.Composable
import androidx.lifecycle.ViewModel
import com.lcg.base.showToast
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import java.io.File

/**
 * viewModel
 *
 * @author lei.chuguang Email:475825657@qq.com
 */
@Composable
inline fun <reified VM : BaseViewModel> viewModel(
    navigator: DestinationsNavigator?, title: String
): VM = androidx.lifecycle.viewmodel.compose.viewModel<VM>()
    .apply { this.navigator = navigator;this.title = title }

/**音频播放ViewModel*/
open class AudioViewModel : BaseViewModel() {
    private var player: MediaPlayer? = MediaPlayer()
    private var currentPlaying: Playing? = null
    var lastSelect: Playing? = null
        private set

    /**释放音乐播放器资源*/
    fun release() {
        currentPlaying?.play = false
        currentPlaying = null
        lastSelect = null
        player?.stop()
        player?.release()
        player = null
    }

    /**直接播放url*/
    fun play(url: String, playing: Playing? = null) {
        if (player == null) {
            currentPlaying = playing
        } else {
            if (currentPlaying?.play == true) {
                currentPlaying?.play = false
                player?.stop()
            }
            currentPlaying = playing?.also { it.play = true }
            if (!url.startsWith("http")) {
                complete(playing)
                return
            }
            try {
                reset(playing, null)
                player!!.setDataSource(url)
                player!!.prepareAsync()
            } catch (_: Exception) {
                complete(playing)
            }
        }
    }

    /**播放*/
    fun play(item: Audio) {
        lastSelect = item
        if (player == null) {
            currentPlaying = item
            complete(item)
        } else {
            if (currentPlaying?.play == true) {
                currentPlaying?.play = false
                player?.stop()
            }
            currentPlaying = item.also { it.play = true }
            //
            val url = item.url
            if (!url.startsWith("http")) {
                complete(item)
                return
            }
            cacheFile(url) {
                if (it == null) {
                    showToast("加载发音文件失败")
                    complete(item)
                } else {
                    if (player == null || currentPlaying != item) {
                        complete(item)
                        return@cacheFile
                    }
                    try {
                        reset(item, it)
                        player!!.setDataSource(it.path)
                        player!!.prepareAsync()
                    } catch (e: Exception) {
                        complete(item)
                    }
                }
            }
        }
    }

    private fun reset(item: Playing?, file: File?) {
        player?.let {
            it.reset()
            it.setOnErrorListener { _, what, _ ->
                file?.delete()
                if (what != -38)
                    showToast("播放失败")
                complete(item)
                true
            }
            it.setOnCompletionListener {
                complete(item)
            }
            it.setOnPreparedListener {
                if (currentPlaying == item)
                    it.start()
            }
        }
    }

    private fun complete(item: Playing?) {
        item?.play = false
        if (currentPlaying == item) {
            currentPlaying = null
        }
    }

    interface Playing {
        var play: Boolean
    }

    interface Audio : Playing {
        val url: String
    }
}